/**
 * @file Dispatcher.h
 * @author BadFatCat0919 (543015378@qq.com)
 * @brief 调度器类
 */

#ifndef __DISPATCHER_H__
#define __DISPATCHER_H__

#include "Robot.h"
#include "Bench.h"
#include "Cmd.h"
#include <list>

/**
 * @brief 调度器
 */
class Dispatcher {
private:
    Robot *robot = nullptr; // 连接的机器人
    std::list<Cmd> cmdSeq; // 指令序列
    enum {
        GET_CMD, // 获取指令
        START_CMD, // 启动指令
        EXECUTE_CMD, // 执行指令
        END_CMD, // 结束指令
        INSERT_CMD, // 插入指令
    } status; // 调度器状态
    Cmd cmd; // 正在执行的指令
    Cmd lastCmd; // 最后一条执行的指令
    Dispatcher *avoidDispatcher = nullptr; // 正在躲避的机器人调度器

public:
    void attach(Robot *robot);
    void loop();
    void pushCmd(Cmd cmd, bool isPushFront = false);
    void pushCmd_RunTo(int x, int y, bool isEmpty = true, bool isPushFront = false);
    void pushCmd_Buy(Bench *bench, bool isPushFront = false);
    void pushCmd_Sell(Bench *bench, int type, bool isPushFront = false);
    void pushCmd_Destroy(bool isPushFront = false);
    void pushCmd_Wait(int waitFrames = 1, bool isPushFront = true);
    bool pushCmd_Avoid(Dispatcher *dispatcher, int minSteps);
    void pushCmd(std::list<Cmd> cmdSeq, bool isPushFront = false);
    void pushCmd(Bench *buy, Bench *sell, bool isPushFront = false);
    void clearCmd();
    Cmd getLastRunto();
    int forecastCrash(int steps, bool anyDirection = false);
    Robot *getRobot();
    Cmd getCmd();
    int isInPath(int x, int y, bool isEmpty, int minSteps);
    bool isAvoid(Dispatcher *avoidDispatcher = nullptr);
    bool isWait();
    bool isFree();
};

#endif // __DISPATCHER_H__
